<template>
  <div
    v-loading="pageLoading"
    :class="isDarkMode(routeName) ? '' : 'pb-[20px]'"
  >
    <div
      v-if="pageHeaderBoards && pageHeaderBoards?.length"
      :class="isDarkMode(routeName) ? 'mt-[0px]' : 'mt-[10px]'"
    >
      <grid-layout
        :layout="pageHeaderBoards"
        :col-num="24"
        :row-height="10"
        :is-draggable="isDesign === 1 ? true : false"
        :is-resizable="isDesign === 1 ? true : false"
        :is-mirrored="false"
        :vertical-compact="true"
        :margin="[10, 0]"
        :use-css-transforms="true"
      >
        <grid-item
          v-for="item in pageHeaderBoards"
          :x="item.x"
          :y="item.y"
          :w="item.w"
          :h="item.h"
          :i="item.i"
          :key="item.i"
          @resized="saveHeaderTemplate"
          @moved="saveHeaderTemplate"
        >
          <component
            :is="item.component"
            v-if="item.name"
            :id="item.i"
            :title="item.name"
            :url="item.url"
            :params="item.params"
            :panelSetIcon="isDesign === 1 ? false : true"
            @delete-panel-item-event="deleteHeaderPanel"
          />
        </grid-item>
      </grid-layout>
    </div>
    <div v-if="!pageHeaderBoards?.length && isDesign === 1" class="header">
      <el-button @click="addTemplate('header')" :icon="Setting"
        >工作台头部</el-button
      >
    </div>
    <div
      class="m-[10px] catalog"
      v-if="isDesign === 1 || (isDesign !== 1 && pageList.length > 1)"
    >
      <el-menu
        :default-active="activeIndex"
        class="el-menu-demo"
        mode="horizontal"
        background-color="transparent"
        text-color="#2979ff"
        active-text-color="#fff"
        @select="handleSelect"
      >
        <el-menu-item
          v-for="(item, itemIndex) in pageList"
          :key="item.id"
          :index="itemIndex + ''"
          >{{ item.pageName }}</el-menu-item
        >
      </el-menu>
    </div>

    <div v-for="(gridItem, gridIndex) in pageList" :key="gridItem.id">
      <div v-if="gridItem.pageObject?.Boards?.length">
        <grid-layout
          v-show="activeIndex === gridIndex.toString()"
          :layout="gridItem.pageObject?.Boards"
          :col-num="24"
          :row-height="10"
          :is-draggable="isDesign === 1 ? true : false"
          :is-resizable="isDesign === 1 ? true : false"
          :is-mirrored="false"
          :vertical-compact="true"
          :margin="[10, 10]"
          :use-css-transforms="true"
        >
          <grid-item
            v-for="(item, index) in gridItem.pageObject?.Boards"
            :x="item.x"
            :y="item.y"
            :w="item.w"
            :h="item.h"
            :i="item.i"
            :key="item.i"
            @resized="saveTemplate"
            @moved="saveTemplate"
          >
            <component
              :is="item.component"
              v-if="item.name"
              :id="item.i"
              :title="item.name"
              :url="item.url"
              :params="item.params"
              :panelSetIcon="isDesign === 1 ? false : true"
              :activeShow="Number(activeIndex) === gridIndex"
              @delete-panel-item-event="deletePanelItem"
            />
          </grid-item>
        </grid-layout>
      </div>
    </div>
    <add-grid-item
      :visible="addDialog.visible"
      :title="addDialog.title"
      :isRadio="addDialog.isRadio"
      :data="addDialog.data"
      @change-visible="changeVisible"
      @add-template="getPanelItem"
    />
    <add-grid-item-button v-if="isDesign === 1" @click-button="addTemplate" />
    <div
      class="side_btn_box1 bg-orange"
      :style="{ cursor: 'pointer' }"
      id="dragElement"
      v-if="isDesign === 1 && route.query.from == 'dashboard'"
      @click="jump"
    >
      更新首页
      <!-- <i-ep-setting color="white" /> -->
      <!-- 插槽出口 -->
      <slot></slot>
    </div>
  </div>
</template>

<script setup lang="ts" name="GridLayoutUse">
import { reactive } from "vue";
import request from "@/utils/request";
import { useRoute } from "vue-router";
import {
  filterDemoTemplateUrl,
  filterDemoTemplateName,
  getRandomNumber,
} from "@/utils/index";
import DemoIframeReport from "../../../demo/gridLayoutUse/components/IframeReport.vue";
import TemplateError from "../../../demo/gridLayoutUse/components/TemplateError.vue";
import { Setting } from "@element-plus/icons-vue";
import router from "@/router";
import { layoutMock } from "@/assets/js/mock";
import { isDarkMode } from "@/utils/index";
const routeName = useRoute().name;

import {
  singlePanel,
  PageObjectItem,
  BoardsObject,
  PageObjectBoards,
  getPanelObject,
  getPosition,
  filterSaveTemplate,
} from "@/assets/js/layout";

const modules = import.meta.glob(
  "../../../../views/demo/gridLayoutUse/components/**/**.vue"
);

// const modules1 = import.meta.glob(
//   "../../../../views/dataScreen/gridLayoutUse/components/**/**.vue"
// );

const route = useRoute();

const props = defineProps({
  // 是否是设计状态  1 编辑状态  2 预览状态
  isDesign: {
    type: Number,
    default: () => {
      return 1;
    },
  },
  // 是否是正式页面  1 正式数据  2 非正式数据
  isProd: {
    type: Number,
    default: () => {
      return 1;
    },
  },
  // 设计页面作为组件使用时的工作台id workbenchId
  id: {
    type: String,
    default: () => {
      return "";
    },
  },
  // 页面
  from: {
    type: String,
    default: () => {
      return "";
    },
  },
});

const { isDesign, isProd, id, from } = toRefs(props);

const workbenchId = route.query.workbenchId || id.value;

/* 
  看板内容 — 页签点击事件
*/
const activeIndex = ref("0");
const handleSelect = (key: string) => {
  activeIndex.value = key;
};

/* 
  ----------------看板内容逻辑展示如下---------------
*/

/* 
  看板内容 — 数据定义
*/
const pageList: any = ref([]);
const pageLoading = ref(false);

/* 
  看板内容 — 获取数据
*/
async function getPageList() {
  try {
    pageLoading.value = true;
    let list = [];
    if (workbenchId) {
      const { data } = await request({
        url: `/system/sysworkbenchpage/getList`,
        method: "post",
        data: {
          workbenchId,
        },
      });
      list = data;
    } else {
      list = layoutMock;
    }
    pageList.value = list;
    pageLoading.value = false;
    pageList.value.length && initPanel();
    if (list.length === 0) {
      isDesign.value === 1 && showAlert();
    }
  } catch (error) {
    pageLoading.value = false;
  }
}

/* 
  看板内容 — 页面管理为空提示
*/
function showAlert() {
  ElMessageBox.confirm("当前工作台未添加页面管理，请立即前往设置", "Warning", {
    confirmButtonText: "立即设置",
    cancelButtonText: "暂不设置",
    type: "warning",
    center: true,
  })
    .then(() => {
      router.push({
        path: "/system/sysworkbenchinfo/workbenchPageManage",
        query: {
          workbenchId: workbenchId,
        },
      });
    })
    .catch(() => {});
}

/* 
  看板头部 —  回显数据
*/
function initPanel() {
  pageList.value.forEach((item: PageObjectItem<PageObjectBoards>) => {
    if (item.pageObject?.Boards?.length) {
      item.pageObject.Boards.forEach((self: BoardsObject) => {
        initPanelHandle(self);
      });
    }
  });
}

/* 
  看板内容 — 回显数据公共处理方法
*/
function initPanelHandle(self: BoardsObject) {
  if (self.type === "1") {
    const component = getComponent(self);
    self.component = shallowRef(component);
  } else {
    self.component = shallowRef(DemoIframeReport);
  }
}

/* 
  看板内容 — 选择模板弹窗
*/
const addDialog = reactive<DialogOption>({
  visible: false,
  title: "",
  isRadio: false,
  data: {},
});
function addTemplate(type?: string) {
  console.log("点击addTemplate");
  if (type) {
    addDialog.isRadio = true;
    addDialog.title = "新增头部看板";
  } else {
    addDialog.isRadio = false;
    addDialog.title = "新增看板";
  }
  addDialog.visible = true;
}
function changeVisible(value: boolean) {
  addDialog.visible = value;
  if (!value) {
    addDialog.data = {};
  }
}

/* 
  看板头部&内容 —  添加模板
*/
function getPanelItem(checkPanels: any[]) {
  if (addDialog.isRadio) {
    // 头部模板
    const checkPanelItem = toRaw(checkPanels)[0];
    let baseName = "";
    let component = null;
    if (checkPanelItem.databoradType === "1") {
      baseName = filterDemoTemplateName(checkPanelItem.databoradUrl);
      component = getComponent(checkPanelItem);
    }
    // 引入内部组件默认位置
    const arr = getPosition(baseName);
    // 设置内部组件object
    const object = getPanelObject(
      singlePanel,
      arr[0],
      checkPanelItem,
      "0",
      component,
      DemoIframeReport,
      workbenchId,
      true
    );
    pageHeaderBoards.value = [object];
    saveHeaderTemplate();
  } else {
    const checkPanelItem = toRaw(checkPanels);
    const newLayout: any = [];
    try {
      const dataBoards =
        pageList.value[Number(activeIndex.value)].pageObject?.Boards || [];
      checkPanelItem.filter((item: any) => {
        // 引入内部组件
        const i =
          ((dataBoards?.length || 0) + newLayout.length).toString() +
          getRandomNumber(0, 90).toString();
        let baseName = "";
        let component = null;
        if (item.databoradType === "1") {
          baseName = filterDemoTemplateName(item.databoradUrl);
          component = getComponent(item);
        }
        // 引入内部组件默认位置
        const arr = getPosition(baseName);
        // 设置内部组件object
        const object = getPanelObject(
          singlePanel,
          arr[0],
          item,
          i,
          component,
          DemoIframeReport,
          workbenchId,
          false
        );
        newLayout.push(object);
      });
      pageList.value[Number(activeIndex.value)].pageObject = {
        Boards: [...toRaw(dataBoards || []), ...newLayout],
      };
      saveTemplate();
    } catch (e) {
      console.log(e);
    }
  }
}

/* 
  看板头部&内容 —  自定义引入组件方法
*/
function getComponent(self: BoardsObject) {
  const baseUrl = filterDemoTemplateUrl(
    self.url ?? self.databoradUrl,
    isProd.value === 1 ? "" : "design"
  );
  const url = `../../../${baseUrl}.vue`;
  let component = null;
  try {
    component = defineAsyncComponent(modules[url] || modules1[url]);
  } catch {
    component = TemplateError;
  }
  return component;
}

/* 
  看板内容 —  删除面板
*/
function deletePanelItem(panelId: any) {
  const dataBoards =
    pageList.value[Number(activeIndex.value)].pageObject.Boards;

  const deleteName = [];
  const layoutList: any = Array.from(dataBoards);
  for (const attr in layoutList) {
    if (layoutList[attr].i === panelId) {
      deleteName.push(layoutList[attr].name);
      delete layoutList[attr];
    }
  }
  pageList.value[Number(activeIndex.value)].pageObject.Boards =
    layoutList.filter((item: any) => {
      if (item !== undefined) {
        return item;
      }
    });
  saveTemplate();
}

/* 
  看板内容 —  保存
*/
const addLoading = ref(false);
async function saveTemplate() {
  try {
    addLoading.value = true;
    const sysWorkbenchPage = filterSaveTemplate(pageList.value);
    const data: any = await request({
      url: `/system/sysworkbenchpage/save`,
      method: "post",
      data: sysWorkbenchPage[Number(activeIndex.value)],
    });
    // data.code === 200 && getPageList();
    addLoading.value = false;
  } catch (error) {
    addLoading.value = false;
  }
}

/* 
  -----------看板头部逻辑展示如下-----------
*/

/* 
  看板头部 — 数据定义
*/
const pageHeaderObject = ref(); // 头部结构体
const pageHeaderBoards = ref(); // 头部看板数据

/* 
  看板头部 — 获取数据
*/
function getPageHeader() {
  request({
    url: `/system/sysworkbenchinfo/get/${workbenchId}`,
    method: "get",
  }).then((data) => {
    pageHeaderObject.value = data.data;
    pageHeaderBoards.value = data.data?.paramObject?.Boards || [];
    initPageHeader();
  });
}

/* 
  看板头部 — 初始化
*/
function initPageHeader() {
  if (pageHeaderBoards.value?.length) {
    pageHeaderBoards.value.forEach((self: BoardsObject) => {
      initPanelHandle(self);
    });
  }
}

/* 
  看板头部 —  保存
*/
async function saveHeaderTemplate() {
  pageHeaderObject.value = {
    ...pageHeaderObject.value,
    paramObject: {
      Boards: pageHeaderBoards.value,
    },
  };
  await request({
    url: `/system/sysworkbenchinfo/save`,
    method: "post",
    data: pageHeaderObject.value,
  });
}

/* 
  看板头部 —  删除
*/
function deleteHeaderPanel() {
  pageHeaderBoards.value = [];
  saveHeaderTemplate();
}

/* 
  ----------页面初始化加载---------------
*/
onMounted(() => {
  getPageList();
  getPageHeader();
});

function jump() {
  router.push({
    path: "/dashboard",
    query: {},
  });
}
</script>

<style lang="scss" scoped>
.side_btn_box1 {
  position: fixed;
  right: 0;
  width: 100px;
  height: 36px;
  border-radius: 6px 0 0 6px;
  bottom: 100px;
  z-index: 200;
  // display: flex;
  // align-items: center;
  // justify-content: center;
  cursor: pointer;
  font-size: 16px;
  color: #fff;
  font-weight: 600;
  line-height: 36px;
  text-align: center;

  svg {
    margin-top: 10px;
    margin-left: 10px;
  }

  @keyframes slide-in {
    70% {
      // opacity: 0.5;
      scale: 0.4;
    }

    100% {
      // opacity: 1;
      scale: 1;
    }
  }

  &:hover {
    // box-shadow: var(--el-box-shadow-dark);

    .el-icon {
      animation: slide-in 0.3s ease-in-out;
    }
  }
}
.vue-grid-item {
  width: 100%;
  height: 100%;
  border-radius: 5px;
}
.active-bar {
  position: relative;
  height: 40px;
  width: 100%;
  .add {
    position: absolute;
    right: 20px;
    bottom: 0;
  }
}
.header {
  height: 80px;
  background-color: antiquewhite;
  background-image: url(../../../../assets/images/bg1.jpg);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  margin: 10px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: var(--el-disabled-text-color);
  font-size: 14px;
}
.catalog {
  position: relative;
}

.catalog {
  margin-bottom: 0px;
  :deep(.el-menu-item.is-active) {
    background-color: #2979ff !important;
  }
  :deep(.el-menu-item) {
    background-color: rgb(239, 240, 253) !important;
    height: 32px;
    line-height: 32px;
    font-size: 14px;
    margin-right: 10px;
    border-radius: 0px;
    padding: 0 30px;
    font-weight: 600;
  }
  :deep(.el-menu--horizontal.el-menu) {
    border-bottom: none !important;
  }
}
</style>
